﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Reborn_WorldServer;
using Reborn_Server.App1AppHandler;

namespace App1AppHandler
{
    public class Creature_GroupRes : Creature
    {
        public Creature_GroupRes(AppHandler2 gameHandler) : base(gameHandler) { }

        private List<Creature_GroupRes> linkedCreatures = new List<Creature_GroupRes>();

        private List<int> groupIds = null;
        private List<int> getGroupIDs()
        {
            if (groupIds == null)
            {
                groupIds = new List<int>();
                
                groupIds.Add(2412);
                groupIds.Add(2413);
            }
            groupIds.Remove(this.ID);

            return groupIds;
        }

        private void findLinkCreatures()
        {
            foreach (int id in getGroupIDs())
            {
                bool creatureFound = false;

                lock (linkedCreatures)
                {
                    foreach (Creature_GroupRes creature in linkedCreatures)
                    {
                        if (creature.ID == id)
                        {
                            creatureFound = true;
                            break;
                        }
                    }
                }

                if (creatureFound == false)
                {
                    Creature templateCreature;
                    if (Managers.GameHandler.AllCreatures.TryGetValue(id, out templateCreature) == false)
                        templateCreature = null;

                    if (templateCreature == null)
                        continue;

                    Map creaturesMap = Managers.GameHandler.GetMap(templateCreature.StartMapID, Instance);
                    if (creaturesMap == null)
                        continue;

                    Creature targetCreature = creaturesMap.findCreatureToProcessByDbId(id);
                    if (targetCreature != null)
                    {
                        lock (linkedCreatures)
                        {
                            linkedCreatures.Add((Creature_GroupRes)targetCreature);
                        }
                    }
                }
            }
        }

        private int linkCreatureDeadCounter = 0;

        private void tryGroupRes()
        {
            LockItem lockItem = Managers.GameHandler.GetLockItem(MapID, Instance);
            lock (lockItem.LockObj)
            {
                //CHECK IF WE'RE IN A VALID STATE TO CONTINUE EXECUTION/////////////////////////

                //System.Reflection.MethodBase currentMethodBase = System.Reflection.MethodBase.GetCurrentMethod();
                //Delegate currentMethodDelegate = Delegate.CreateDelegate(currentMethodBase.GetType(), this, currentMethodBase.Name);

                //Create a delegate for this method incase it cant be run right now
                Action thisMethod = (Action)tryGroupRes;
                //Record this method's arguments
                Object[] thisMethodArgs = { null };
                //Pass the delegate and args when we check if we're mid map transfer. If yes, they will be recorded and run again automatically.
                if (isChangingMaps(thisMethod, thisMethodArgs) == true)
                    return;

                //A map transfer happened, but its already complete. Immediately re-run this method on a different thread. 
                //We need to use a different thread because otherwise the current thread would lock 2 maps possibly resulting in a deadlock.
                if (MapID != lockItem.MapID)
                {
                    thisMethod.BeginInvoke(null, null);
                    return;
                }
                //STATE IS VALID, CONTINUE EXECUTION///////////////////////////////////////////

                if (HP < 1)
                    return;

                bool creatureDead = false;
                lock (linkedCreatures)
                {
                    if (linkedCreatures.Count != getGroupIDs().Count)
                        findLinkCreatures();

                    if (linkedCreatures.Count == 0)
                        return;

                    foreach (Creature_GroupRes creature in linkedCreatures)
                    {
                        if (creature.HP < 1)
                        {
                            creatureDead = true;
                            break;
                        }
                    }
                }

                if (creatureDead == false)
                    linkCreatureDeadCounter = 0;
                else
                    linkCreatureDeadCounter++;

                if (linkCreatureDeadCounter >= 5)
                {
                    lock (linkedCreatures)
                    {
                        foreach (Creature_GroupRes creature in linkedCreatures)
                        {
                            if (creature.HP < 1)
                            {
                                Message msg = new Message();
                                msg.CreatureID = this.CreatureID;
                                msg.Text = Name + ": Rise again my lord!";
                                msg.Type = "say";

                                MessageBroadcast(currentMapItem.mapItemsWithin4, msg, false);

                                creature.creatureAI.forceRespawn();
                            }
                        }
                    }
                }
            }
        }

        public override void runAI()
        {
            base.runAI();

            tryGroupRes();
        }

        public override void DropLoot(int SlayingCharID)
        {
            bool lastAlive = true;

            lock (linkedCreatures)
            {
                foreach (Creature_GroupRes creature in linkedCreatures)
                {
                    if (creature.HP > 0)
                    {
                        lastAlive = false;
                        break;
                    }
                }
            }

            if (lastAlive)
            {
                base.DropLoot(SlayingCharID);
            }
            else
            {
                Message msg = new Message();
                msg.CreatureID = this.CreatureID;
                msg.Text = Name + ": You think you can kill me that easily?! I'll see you soon!";
                msg.Type = "say";

                MessageBroadcast(currentMapItem.mapItemsWithin4, msg, false);
            }
        }
    }
}
